package org.sja.log2traffic;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

import org.joda.time.DateTime;
import org.sja.log2traffic.dataStructures.ChartPeriodEnum;
import org.sja.log2traffic.dataStructures.ConfigurationEntity;


public class ConfigurationManipulator {

	private IDateTimeFormatter dataCalculator;

	public ConfigurationManipulator(IDateTimeFormatter dataCalculator) {
		this.dataCalculator = dataCalculator;
	}

	public ConfigurationEntity getConfiguration(String configurationName, String from, String to, ChartPeriodEnum chartPeriodEnum) {
		DateTime from_dt = new DateTime(dataCalculator.stringWithMinutesToLong(from));
		DateTime to_dt = new DateTime(dataCalculator.stringWithMinutesToLong(to));
		if (chartPeriodEnum == ChartPeriodEnum.DAY) {
			from_dt = from_dt.dayOfMonth().roundFloorCopy();
			to_dt = to_dt.dayOfMonth().roundFloorCopy();
		} else if (chartPeriodEnum == ChartPeriodEnum.HOUR) {
			from_dt = from_dt.hourOfDay().roundFloorCopy();
			to_dt = to_dt.hourOfDay().roundFloorCopy();
		} else if (chartPeriodEnum == ChartPeriodEnum.MINUTE) {
			from_dt = from_dt.minuteOfHour().roundFloorCopy();
			to_dt = to_dt.minuteOfHour().roundFloorCopy();
		}
		ConfigurationEntity configurationFromTo = new ConfigurationEntity(configurationName, dataCalculator, chartPeriodEnum);
		loadConfiguration(configurationFromTo, configurationName, "Hours");
		configurationFromTo.setFrom(from_dt.getMillis());
		configurationFromTo.setTo(to_dt.getMillis());
		return configurationFromTo;
	}

	public ConfigurationEntity getConfigurationForMonthsReport(String configurationName) {
		DateTime now = getNowRoundedToDays();
		ConfigurationEntity configurationFromTo = new ConfigurationEntity(configurationName, dataCalculator, ChartPeriodEnum.DAY);
		loadConfiguration(configurationFromTo, configurationName, "Months");
		configurationFromTo.setTo(now.getMillis());
		Integer amount = configurationFromTo.getAmountOfMonthsOnMonthsChart();
		configurationFromTo.setFrom(now.minusMonths(amount).getMillis());
		return configurationFromTo;
	}

	public ConfigurationEntity getConfigurationForWeeksReport(String configurationName) {
		DateTime now = getNowRoundedToDays();
		ConfigurationEntity configurationFromTo = new ConfigurationEntity(configurationName, dataCalculator, ChartPeriodEnum.DAY);
		loadConfiguration(configurationFromTo, configurationName, "Weeks");
		configurationFromTo.setTo(now.getMillis());
		Integer amount = configurationFromTo.getAmountOfWeeksOnWeeksChart();
		configurationFromTo.setFrom(now.minusWeeks(amount).getMillis());		
		return configurationFromTo;
	}

	public ConfigurationEntity getConfigurationForDaysReport(String configurationName) {
		DateTime now = getNowRoundedToHours();
		ConfigurationEntity configurationFromTo = new ConfigurationEntity(configurationName, dataCalculator, ChartPeriodEnum.HOUR);
		loadConfiguration(configurationFromTo, configurationName, "Days");
		configurationFromTo.setTo(now.getMillis());
		Integer amount = configurationFromTo.getAmountOfDaysOnDaysChart();
		configurationFromTo.setFrom(now.minusDays(amount).getMillis());			
		return configurationFromTo;
	}

	public ConfigurationEntity getConfigurationForHoursReport(String configurationName) {
		DateTime now = getNowRoundedToMinutes();
		ConfigurationEntity configurationFromTo = new ConfigurationEntity(configurationName, dataCalculator, ChartPeriodEnum.MINUTE);
		loadConfiguration(configurationFromTo, configurationName, "Hours");
		configurationFromTo.setTo(now.getMillis());
		Integer amount = configurationFromTo.getAmountOfHoursOnHoursChart();
		configurationFromTo.setFrom(now.minusHours(amount).getMillis());		
		return configurationFromTo;
	}
	
	private DateTime getNowRoundedToHours() {
		return new DateTime().hourOfDay().roundFloorCopy();
	}

	private DateTime getNowRoundedToDays() {
		return new DateTime().dayOfMonth().roundFloorCopy();
	}

	private DateTime getNowRoundedToMinutes() {
		return new DateTime().minuteOfHour().roundFloorCopy();
	}

	private void loadConfiguration(ConfigurationEntity configuration, String configurationFilename, String subdir) {
		Properties properties = new Properties();
		FileReader fileReader = null;
		try {
			fileReader = new FileReader(new File(configurationFilename));
			properties.load(fileReader);
			String rootOutputDirStr = properties.getProperty("outputDirectory");
			File rootOutputDirectory = new File(rootOutputDirStr);
			File outputSpecificDirectory = new File(rootOutputDirStr + "/" + subdir);
			configuration.setRootOutputConfigurationDirectory(rootOutputDirectory);
			configuration.setOutputDirectory(outputSpecificDirectory);

			String[] parsed = properties.getProperty("inputDirectories").split(",");
			File[] inputDirectories = new File[parsed.length];
			for (int i = 0; i < parsed.length; ++i) {
				String fileToCheck = parsed[i].trim();
				File file = new File(fileToCheck);
				inputDirectories[i] = file;
			}
			configuration.setInputDirectories(inputDirectories);
			
			String environment = properties.getProperty("traffic_environment");
			configuration.setTrafficEnvironment(environment);

			@SuppressWarnings("unchecked")
			Class<? extends ILogDataModyficator> clazz = (Class<? extends ILogDataModyficator>)Class.forName(properties.getProperty("loglineParserClass"));
			configuration.setLogLineParserClass(clazz);
			
			String logFileNameStartWith= properties.getProperty("logFileNameStartWith");
			configuration.setLogFileNameStartWith(logFileNameStartWith);

			Integer amountOfMonthsOnMonthsChart = Integer.parseInt(properties.getProperty("amountOfMonthsOnMonthsChart"));
			configuration.setAmountOfMonthsOnMonthsChart(amountOfMonthsOnMonthsChart);

			Integer amountOfWeeksOnWeeksChart = Integer.parseInt(properties.getProperty("amountOfWeeksOnWeeksChart"));
			configuration.setAmountOfWeeksOnWeeksChart(amountOfWeeksOnWeeksChart);

			Integer amountOfDaysOnDaysChart = Integer.parseInt(properties.getProperty("amountOfDaysOnDaysChart"));
			configuration.setAmountOfDaysOnDaysChart(amountOfDaysOnDaysChart);

			Integer amountOfHoursOnHoursChart = Integer.parseInt(properties.getProperty("amountOfHoursOnHoursChart"));
			configuration.setAmountOfHoursOnHoursChart(amountOfHoursOnHoursChart);

			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (fileReader != null) {
				try {
					fileReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}


}
